[iOS 9]Xcode 6.3+Swift 1.2のプロジェクトをXcode 7.1+Swift 2.1に対応した時の話
はじめに
モバイルアプリサービス部の田中孝明です。
弊社でのXcode 6.3+Swift 1.2のプロジェクトをXcode 7.1+Swift 2.1に移行した際の対応内容で気がついた点を列挙しました。
ご参考になれば幸いです。
移行前の環境について
- Xcode 6.3
- Deployment target 7.0
- Swift 1.2
- Submodule
- CocoaPods
CocoaPodsはObjective-Cの外部ライブラリを、SubmoduleはSwiftの外部ライブラリをインポートする為に導入していました。 iOS 7をサポートするため、ライブラリ管理の二重構成となっていました。
Deployment Targetを8.0に変更
SubmoduleでSwiftのライブラリを管理していたのですが元がSwift 1.2のコードだったということもあり、Xcode 7.1でビルドが通らなくなりました。
そこでSwift 2.1に対応したリポジトリを設定し、Submoduleをアップデートしました。
ところが一部のライブラリ同士で同じ名前のクラスResultが競合するようになってしまいました。
Submoduleで読み込んでいる部分を別Targetに設定する方法などを模索していましたが プロジェクト構成も煩雑になるため、別の手段を講じることにしました。
その一つがCocoaPodsでDynamic Libraryを利用することでした。
前述のResultクラスの依存関係も解消でき、Submodule・CocoaPodsによるライブラリ管理の二重構成も解消されるため、できればこの方法をと考えていました。
もちろん弊害もあり、Dynamic Libraryをサポートするためには対応iOSを8以上にする必要があるため、 iOS 7のサポートを打ち切らなければならないことでした。
弊社ではお客様にご理解いただいた上、iOS 8以上を対象にすることにしました。
CocoaPodsの変更
CocoaPodsで新たにライブラリを一元管理するためにPodfileを修正しました。
Submoduleで利用していた外部ライブラリの全てがCocoaPodsに対応していたため、こちらは容易に行うことができました。
Podfileのplatformを7.0から8.0に修正します。
Podfileにuse_framework!と必要なライブラリを追加します。
Swift 1.2 から 2.1に移行
Xcodeには以下のメニューで最新のSwiftの記述方法に自動で変換する方法が提供されています。
[Edit]>[Convert]>[To Latest Swift Syntax...]
新たに追加された「try」などの構文に関してはこちらで対応することができましたが、 外部ライブラリのインターフェースの変更については手動で直す必要があります。
以下は主な修正点です
- 外部ライブラリのインターフェースの変更対応
- Objctive-Cの外部ライブラリを利用しているソースにインポートを記述する
- Objctive-Cの外部ライブラリもDynamic Libraryになったため
- Swift 2で拡張されたSequenceTypeを対応する
- foreachとしてmapを利用していたところをforEachに置き換える
- 利用されていない変数を削除
規模次第だとは思いますが、地道に一個ずつエラー・警告を対応していくことになります。
iOS 9対応
主に以下の点を対応しました。
- deprecated methodの変更
- propertyのOptional対応
- ATS対応
- 画面の修正
画面の修正に関しては元々StoryboardでAuto Layoutを使用して作成されていたこともあり、大きな修正は発生しませんでした。
まとめ
掲題の対応を行うことで環境が以下のように更新されました。
- Xcode 7.1
- Deployment target 8.0
- Swift 2.1
- CocoaPods
ライブラリの二重管理がなくなったことでシンプルな構成になったのではないかと思います。
以下は気がついた点です。
- テストコードを書いておくこと(テストコードの修正工数もあるが、対応しておくと警告対応の際に便利)
- iOS 8以降のサポートにすることでメンテナンスがしやすくなった
- Swiftのコンパイル速度が上がった(要検証)